package pay

import (
	"context"
	"fmt"
	"git.900sui.cn/kc/base/common/functions"
	"git.900sui.cn/kc/base/common/toolLib"
	"git.900sui.cn/kc/rpcPay/common/lib"
	"git.900sui.cn/kc/rpcPay/common/models"
	_const "git.900sui.cn/kc/rpcPay/lang/const"
	"git.900sui.cn/kc/rpcinterface/interface/bus"
	"git.900sui.cn/kc/rpcinterface/interface/order"
	pay2 "git.900sui.cn/kc/rpcinterface/interface/pay"
	"github.com/shopspring/decimal"
	"github.com/tidwall/gjson"
	"strings"
)

/**
 * @className pingan
 * @author liyang<654516092@qq.com>
 * @date 2021/4/8 15:56
 */

type pinganpay struct {
}

//生成二维码
func (p *pinganpay) PayQr(payInfo *pay2.PayInfo) (string, error) {
	return "", nil
}

//h5支付-收银台
func (p *pinganpay) PayH5(payInfo *pay2.PayInfo) (string, error) {
	err := lib.PinganPay.Init(payInfo.Cid)
	if err != nil {
		return "", err
	}
	return lib.PinganPay.PayH5(payInfo)
}

//h5 升级版本
func (p *pinganpay) PayH5New(payInfo *pay2.PayInfo, ps *pay2.PayH5) (err error) {
	return nil
}

//微信小程序付款
func (p *pinganpay) PayWxApp(payInfo *pay2.PayInfo) (*gjson.Result, error) {
	err := lib.PinganPay.Init(payInfo.Cid)
	if err != nil {
		return nil, err
	}
	return lib.PinganPay.PayWxProgram(payInfo)
}

// 微信公众号支付
func (p *pinganpay) PayWxOfficial(payInfo *pay2.PayInfo) (*gjson.Result, error) {
	err := lib.PinganPay.Init(payInfo.Cid)
	if err != nil {
		return nil, err
	}
	return lib.PinganPay.PayWxOfficial(payInfo)
}

// APP支付【微信/支付宝】-直连
func (p *pinganpay) PayApp(payInfo *pay2.PayInfo) (*gjson.Result, error) {
	err := lib.PinganPay.Init(payInfo.Cid)
	if err != nil {
		return nil, err
	}
	if payInfo.ChosePayType == order.CHOSE_PAY_TYPE_PINGAN_WX {
		return lib.PinganPay.PayWxApp(payInfo)
	} else {
		return lib.PinganPay.PayAliApp(payInfo)
	}
}

//获取支付签名字符串
func (p *pinganpay) PayAppSign(payInfo *pay2.PayInfo) (string, error) {
	return "", nil
}

//异步回调通知 raw json
func (p *pinganpay) Notify(data string) (*pay2.PayNotify, error) {
	sourcegJson := gjson.Parse(data)
	//区域
	channelArea := int(sourcegJson.Get("channelArea").Int())
	channelPay := sourcegJson.Get("channelPay").String()
	err := lib.PinganPay.Init(channelArea)
	if err != nil {
		return nil, err
	}
	gData, err1 := lib.PinganPay.Notify(data, channelPay)
	if err1 != nil {
		return nil, err1
	}
	var payTime int64
	var orderSn, paySn, payFee, payAmount string
	var payChannel, payType int
	if channelPay == lib.CHANNELPAY_pingan {
		//平安云收款
		//验证订单支付状态
		if gData.Get("OrderStatus").String() != "1" {
			return nil, toolLib.CreateKcErr(_const.PAY_ERROR)
		}
		//付款时间
		payTime = functions.StrtoTime(gData.Get("PaySuccessTime").String(), "20060102150405")
		//金额-分转换
		fen := decimal.NewFromInt(100)
		//付款金额-渠道返回单位：分
		amount := decimal.NewFromInt(gData.Get("TranAmt").Int()).Div(fen)
		payAmount = amount.String()
		//平安银行云收款手续费按照单笔0.65% 计算
		payRate := decimal.NewFromFloat(0.0065)
		//支付手续费
		payFee = amount.Mul(payRate).Round(2).Truncate(2).String()
		//商户订单号
		orderSn = gData.Get("TraderOrderNo").String()
		//支付渠道支付流水号
		paySn = gData.Get("ChannelOrderNo").String()
		payChannel = order.PAY_CHANNEL_pingan
		payType = order.PAY_TYPE_YUAN
	} else if channelPay == lib.CHANNELPAY_ali {
		//支付宝直连
		if gData.Get("trade_status").String() != "TRADE_SUCCESS" {
			return nil, fmt.Errorf("交易失败，交易状态描述 :%s", gData.Get("trade_status").String())
		}
		///付款时间
		payTime = functions.StrtoTime(gData.Get("notify_time").String(), "2006-01-02 15:04:05")
		//付款金额-渠道返回单位：元
		amount, _ := decimal.NewFromString(gData.Get("total_amount").String())
		payAmount = amount.String()
		//支付宝收单手续费按照单笔0.6% 计算
		payRate := decimal.NewFromFloat(0.006)
		//支付手续费
		payFee = amount.Mul(payRate).Round(2).Truncate(2).String()
		//商户订单号
		orderSn = gData.Get("out_trade_no").String()
		//支付渠道支付流水号
		paySn = gData.Get("trade_no").String()
		payChannel = order.PAY_CHANNEL_pingan
		payType = order.PAY_TYPE_ALI
	} else if channelPay == lib.CHANNELPAY_wx {
		//微信直连
		if gData.Get("trade_state").String() != "SUCCESS" {
			return nil, fmt.Errorf("交易失败，交易状态描述 :%s", gData.Get("trade_state_desc").String())
		}
		//支付时间
		time := strings.Split(gData.Get("success_time").String(), "+")
		payTime = functions.StrtoTime(time[0], "2006-01-02T15:04:05")

		//付款金额-渠道返回单位：分
		amountData := gjson.Parse(gData.Get("amount").String())

		////金额-分转换
		fen := decimal.NewFromInt(100)
		////付款金额由分转元
		amount := decimal.NewFromInt(amountData.Get("total").Int()).Div(fen)
		payAmount = amount.String()

		//手续费按照单笔0.6% 计算
		payRate := decimal.NewFromFloat(0.006)
		//支付手续费
		payFee = amount.Mul(payRate).Round(2).Truncate(2).String()
		//商户订单号
		orderSn = gData.Get("out_trade_no").String()
		//支付渠道支付流水号
		paySn = gData.Get("transaction_id").String()
		payChannel = order.PAY_CHANNEL_pingan
		payType = order.PAY_TYPE_WX
	}
	return &pay2.PayNotify{
		OrderSn:    orderSn,
		PayTime:    payTime,
		PayAmount:  payAmount,
		PayFee:     payFee,
		PaySn:      paySn,
		PayStatus:  pay2.PAY_Suc,
		PayChannel: payChannel,
		PayType:    payType,
	}, nil
}

//异步回调响应
func (p *pinganpay) NotifyResponse(ctx context.Context, args *pay2.ArgsNotify) (*pay2.ReplyNotifyResponse, error) {
	return nil, nil
}

// 获取支付成功后金额处理
func (s *pinganpay) PayFund(notify *pay2.PayNotify, bill *order.ReplyGetOrderSplitBill) []bus.FundRecordItem {
	return []bus.FundRecordItem{
		{
			OrderSn:  notify.OrderSn,
			Amount:   notify.PayAmount,
			FundType: bus.FUND_TYPE_pay_in,
		}, {
			OrderSn:  notify.OrderSn,
			Amount:   notify.PayFee,
			FundType: bus.FUND_TYPE_bankfee_out,
		}, {
			OrderSn:  notify.OrderSn,
			Amount:   decimal.NewFromFloat(bill.InsureAmount).String(),
			FundType: bus.FUND_TYPE_insurance_out,
		}, {
			OrderSn:  notify.OrderSn,
			Amount:   decimal.NewFromFloat(bill.RenewInsureAmount).String(),
			FundType: bus.FUND_TYPE_reinsurance_out,
		}, {
			OrderSn:  notify.OrderSn,
			Amount:   decimal.NewFromFloat(bill.PlatformAmount).String(),
			FundType: bus.FUND_TYPE_plat_out,
		}, {
			OrderSn:  notify.OrderSn,
			Amount:   decimal.NewFromFloat(bill.DepositAmount).String(),
			FundType: bus.FUND_TYPE_depository,
		}, {
			OrderSn:  notify.OrderSn,
			Amount:   decimal.NewFromFloat(bill.BusAmount).Sub(decimal.NewFromFloat(bill.DepositAmount)).String(),
			FundType: bus.FUND_TYPE_usable,
		},
	}
}

// 获取清分金额
func (p *pinganpay) GetFundAmount(notify *pay2.PayNotify, bill *order.ReplyGetOrderSplitBill) string {
	return ""
}

//获取支付方式
func (p *pinganpay) GetType() int {
	return order.PAY_CHANNEL_pingan
}
func (p *pinganpay) AgentChannel(busClearingModel *models.BusClearingModel, list map[string]interface{}) (id int, err error) {
	return
}
func (p *pinganpay) FundAgent(ctx context.Context) (rest bool) {
	return
}
func (p *pinganpay) FundAgentResult(ctx context.Context) (rest bool) {
	return
}

func (p *pinganpay) GetInsureFund() bool {
	return false
}

func (p *pinganpay) AgentChannelInsure(insureClearingModel *models.InsureClearingModel, list map[string]interface{}) (id int, err error) {
	return
}

func (p *pinganpay) AgentChannelPlat(platClearingModel *models.PlatformClearingModel, list map[string]interface{}) (id int, err error) {
	return
}

func (p *pinganpay) AgentChannelRenewInsure(renewInsureClearingModel *models.RenewInsureClearingModel, list map[string]interface{}) (id int, err error) {
	return
}
